package com.xdcplus.web.service.wip.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.xdcplus.core.utils.BeanUtils;
import com.xdcplus.etl.schedule.annotation.Job;
import com.xdcplus.exceptions.XdcWebException;
import com.xdcplus.exceptions.domain.ResponseVO;
import com.xdcplus.mom.constants.NumberConstant;
import com.xdcplus.mom.constants.RequestConstant;
import com.xdcplus.mom.enums.ResponseEnum;
import com.xdcplus.mom.utils.AuthUtils;
import com.xdcplus.mom.utils.DateUtils;
import com.xdcplus.mom.utils.ResponseUtils;
import com.xdcplus.mp.service.impl.BaseServiceImpl;
import com.xdcplus.mp.utils.PageableUtils;
import com.xdcplus.mp.utils.PropertyUtils;
import com.xdcplus.pager.vo.PageVO;
import com.xdcplus.system.api.SysEncodeRuleRemote;
import com.xdcplus.system.api.UserInfoRemote;
import com.xdcplus.system.api.dto.GenEncodeDTO;
import com.xdcplus.system.api.vo.UserInfoVO;
import com.xdcplus.web.common.config.MarkingSwitchProperties;
import com.xdcplus.web.common.enums.wip.MarkingStatusEnum;
import com.xdcplus.web.common.pojo.dto.*;
import com.xdcplus.web.common.pojo.dto.wip.WipMarkingDTO;
import com.xdcplus.web.common.pojo.dto.wip.WipMarkingFilterDTO;
import com.xdcplus.web.common.pojo.dto.wip.WipMarkingPrdFilterDTO;
import com.xdcplus.web.common.pojo.entity.WipMarkingElSummary;
import com.xdcplus.web.common.pojo.entity.WipMarkingIvCount;
import com.xdcplus.web.common.pojo.entity.WipMarkingIvSummary;
import com.xdcplus.web.common.pojo.entity.WipMarkingPackInfo;
import com.xdcplus.web.common.pojo.entity.bd.BdPath;
import com.xdcplus.web.common.pojo.entity.pm.PmWo;
import com.xdcplus.web.common.pojo.entity.qa.QaMtrlBatchReport;
import com.xdcplus.web.common.pojo.entity.trace.TracePrdInfo;
import com.xdcplus.web.common.pojo.entity.wip.*;
import com.xdcplus.web.common.pojo.query.bd.BdPathQuery;
import com.xdcplus.web.common.pojo.query.wip.WipMarkingQuery;
import com.xdcplus.web.common.pojo.vo.WipMarkingElSummaryVO;
import com.xdcplus.web.common.pojo.vo.WipMarkingIvCountVO;
import com.xdcplus.web.common.pojo.vo.WipMarkingIvSummaryVO;
import com.xdcplus.web.common.pojo.vo.WipMarkingPackInfoVO;
import com.xdcplus.web.common.pojo.vo.bd.BdOpeVO;
import com.xdcplus.web.common.pojo.vo.qa.ElSummaryVO;
import com.xdcplus.web.common.pojo.vo.qa.IvSummaryCountVO;
import com.xdcplus.web.common.pojo.vo.qa.OpenStartAndEndTimeVO;
import com.xdcplus.web.common.pojo.vo.wip.WipMarkingPrdVO;
import com.xdcplus.web.common.pojo.vo.wip.WipMarkingRecordVO;
import com.xdcplus.web.common.pojo.vo.wip.WipMarkingReportVO;
import com.xdcplus.web.common.pojo.vo.wip.WipMarkingVO;
import com.xdcplus.web.component.CommonHelperService;
import com.xdcplus.web.mapper.bd.BdPathMapper;
import com.xdcplus.web.mapper.trace.TracePrdInfoMapper;
import com.xdcplus.web.mapper.wip.WipMarkingBoxMapper;
import com.xdcplus.web.mapper.wip.WipMarkingMapper;
import com.xdcplus.web.mapper.wip.WipMarkingPrdMapper;
import com.xdcplus.web.mapper.wip.WipMarkingReminderMapper;
import com.xdcplus.web.service.CommonService;
import com.xdcplus.web.service.bd.BdOpeService;
import com.xdcplus.web.service.pm.PmWoService;
import com.xdcplus.web.service.wip.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * 打标管理表(WipMarking)表服务实现类
 *
 * @author Devin.sang
 * @since 2023-05-15 22:05:44
 */
@Slf4j
@Service("wipMarkingService")
public class WipMarkingServiceImpl extends BaseServiceImpl<WipMarkingMapper, WipMarking, WipMarking, WipMarkingVO> implements WipMarkingService {

    @Autowired
    protected WipMarkingMapper wipMarkingMapper;

    @Autowired
    protected WipMarkingReminderMapper wipMarkingReminderMapper;

    @Autowired
    protected WipMarkingBoxMapper wipMarkingBoxMapper;

    @Autowired
    protected SysEncodeRuleRemote sysEncodeRuleRemote;

    @Autowired
    protected WipMarkingReminderService wipMarkingReminderService;

    @Autowired
    protected WipMarkingBoxService wipMarkingBoxService;

    @Autowired
    protected WipMarkingRecordService wipMarkingRecordService;

    @Autowired
    protected WipMarkingPrdService wipMarkingPrdService;

    @Autowired
    protected TransactionTemplate transactionTemplate;

    @Autowired
    protected BdOpeService bdOpeService;

    @Autowired
    private TracePrdInfoMapper tracePrdInfoMapper;


    @Autowired
    private BdPathMapper bdPathMapper;

    @Autowired
    private WipMarkingPrdMapper wipMarkingPrdMapper;

    @Autowired
    protected UserInfoRemote userInfoRemote;

    @Autowired
    protected WipUnpackPlanService wipUnpackPlanService;

    @Autowired
    protected PmWoService pmWoService;
    @Autowired
    private  WipMarkingElSummaryService wipMarkingElSummaryService;
    @Autowired
    private WipMarkingIvCountService wipMarkingIvCountService;
    @Autowired
    private  WipMarkingIvSummaryService wipMarkingIvSummaryService;
    @Autowired
    private  WipMarkingPackInfoService wipMarkingPackInfoService;
    @Autowired
    private WipMarkingScreenService wipMarkingScreenService;
    @Autowired
    private MarkingSwitchProperties markingSwitchProperties;

    private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
            4,
            0,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(512),
            new ThreadPoolExecutor.DiscardOldestPolicy());

    @Override
    @DSTransactional
    public Boolean saveWipMarking(WipMarkingDTO wipMarkingDTO) {

        /// marking溯源码
        GenEncodeDTO genEncodeDTO = new GenEncodeDTO();
        genEncodeDTO.setRuleCode(RequestConstant.RULE_UNPACK_EXPERIMENT_CODE);
        genEncodeDTO.setNumber(1L);
        ResponseVO<List<String>> markingEncodeRepsonse = sysEncodeRuleRemote.genEncode(genEncodeDTO);
        List<String> markingCodes = ResponseUtils.getResponse(markingEncodeRepsonse);

        WipMarking wipMarking = new WipMarking();
        BeanUtil.copyProperties(wipMarkingDTO, wipMarking);

        wipMarking.setMarkCode(markingCodes.get(0));
        wipMarking.setCreatedTime(new Timestamp(DateUtil.current()));

        // 查询单片信息
        BdPathQuery bdPathQuery = new BdPathQuery();
        bdPathQuery.setCrOpeCode(wipMarkingDTO.getStartOpeCode());
        List<BdPath> bdPaths = bdPathMapper.queryBdPath(bdPathQuery);

        String pvOpeCode = bdPaths.get(0).getPvOpeCode();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime createdTime = wipMarking.getCreatedTime().toLocalDateTime();
        String createdTimeStr = createdTime.format(formatter);
        LocalDateTime eightHoursAgo = createdTime.minusHours(8);
        String eightHoursAgoStr = eightHoursAgo.format(formatter);

        // 出站时间+花篮号+工序
        List<TracePrdInfo> tracePrdInfos = tracePrdInfoMapper.queryTracePrdInfo(eightHoursAgoStr, createdTimeStr, pvOpeCode, wipMarkingDTO.getWipBoxs());

        if (CollUtil.isEmpty(tracePrdInfos)) {
            throw new XdcWebException(-1, "未查询到对应工序单片信息");
        }
        List<WipMarkingPrd> wipMarkingRecords = tracePrdInfos.stream().map(tracePrdInfo -> {
            WipMarkingPrd wipMarkingPrd = new WipMarkingPrd();
            wipMarkingPrd.setMarkingIdFk(wipMarking.getId());
            wipMarkingPrd.setMarkCode(wipMarking.getMarkCode());
            wipMarkingPrd.setPrdCode(tracePrdInfo.getPrdCode());
            return wipMarkingPrd;
        }).collect(Collectors.toList());

        transactionTemplate.executeWithoutResult(transactionStatus -> {

            this.save(wipMarking);

            /// 提醒人
            List<WipMarkingReminder> wipMarkingReminders = wipMarkingDTO.getReminders().stream().map(reminder -> {
                WipMarkingReminder wipMarkingReminder = new WipMarkingReminder();
                wipMarkingReminder.setMarkingIdFk(wipMarking.getId());
                wipMarkingReminder.setMarkCode(wipMarking.getMarkCode());
                wipMarkingReminder.setUserId(reminder);
                return wipMarkingReminder;
            }).collect(Collectors.toList());
            wipMarkingReminderService.saveBatch(wipMarkingReminders);

            /// 标记花篮
            List<WipMarkingBox> wipMarkingBoxs = wipMarkingDTO.getWipBoxs().stream().map(
                    wipBox -> {
                        WipMarkingBox wipMarkingBox = new WipMarkingBox();
                        wipMarkingBox.setMarkingIdFk(wipMarking.getId());
                        wipMarkingBox.setBoxCode(wipBox);
                        wipMarkingBox.setCreatedTime(Timestamp.from(Instant.now()));
                        wipMarkingBox.setCreatedUser(AuthUtils.getCurrentUser());
                        return wipMarkingBox;
                    }
            ).collect(Collectors.toList());
            wipMarkingBoxService.saveBatch(wipMarkingBoxs);

            // 标记单片
            wipMarkingPrdService.saveBatch(wipMarkingRecords);

        });

        return true;

    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean updateWipMarking(WipMarkingDTO wipMarkingDTO) {

        WipMarking wipMarking = this.getById(wipMarkingDTO.getId());
        if (ObjectUtil.isNull(wipMarking)) {
            log.error("updateWipMarking() The WipMarking does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }

        BeanUtil.copyProperties(wipMarkingDTO, wipMarking);
        wipMarking.setUpdatedUser(wipMarkingDTO.getUpdatedUser());
        wipMarking.setUpdatedTime(new Timestamp(DateUtil.current()));

        AtomicBoolean result = new AtomicBoolean(false);
        transactionTemplate.executeWithoutResult(transactionStatus -> {

            result.set(this.updateById(wipMarking));

            /// 提醒人
            List<WipMarkingReminder> wipMarkingReminders = wipMarkingDTO.getReminders().stream().map(reminder -> {
                WipMarkingReminder wipMarkingReminder = new WipMarkingReminder();
                wipMarkingReminder.setMarkingIdFk(wipMarking.getId());
                wipMarkingReminder.setMarkCode(wipMarking.getMarkCode());
                wipMarkingReminder.setUserId(reminder);
                return wipMarkingReminder;
            }).collect(Collectors.toList());
            LambdaQueryWrapper<WipMarkingReminder> wipMarkingReminderLambdaQueryWrapper = new LambdaQueryWrapper<>();
            wipMarkingReminderLambdaQueryWrapper.eq(WipMarkingReminder::getMarkingIdFk, wipMarking.getId());
            wipMarkingReminderMapper.delete(wipMarkingReminderLambdaQueryWrapper);
            wipMarkingReminderService.saveBatch(wipMarkingReminders);

            /// 标记花篮
            List<WipMarkingBox> wipMarkingBoxs = wipMarkingDTO.getWipBoxs().stream().map(
                    wipBox -> {
                        WipMarkingBox wipMarkingBox = new WipMarkingBox();
                        wipMarkingBox.setMarkingIdFk(wipMarking.getId());
                        wipMarkingBox.setBoxCode(wipBox);
                        wipMarkingBox.setCreatedTime(Timestamp.from(Instant.now()));
                        wipMarkingBox.setCreatedUser(AuthUtils.getCurrentUser());
                        return wipMarkingBox;
                    }
            ).collect(Collectors.toList());
            wipMarkingBoxService.saveBatch(wipMarkingBoxs);

        });

        return result.get();

    }

    @Override
    public Boolean saveOrUpdateBatch(List<WipMarking> wipMarkingList) {

        wipMarkingList.forEach(wipMarking -> {
            WipMarking wipMarkingParam = new WipMarking();
            wipMarkingParam.setId(wipMarking.getId());
            if (ObjectUtil.isNotNull(wipMarking.getId())) {
                wipMarking.setId(wipMarking.getId());
                wipMarking.setUpdatedTime(new Timestamp(DateUtil.current()));
                LambdaUpdateWrapper<WipMarking> lambdaUpdate = Wrappers.lambdaUpdate();
                lambdaUpdate.eq(WipMarking::getId, wipMarking.getId());
                update(wipMarking, lambdaUpdate);
            } else {
                wipMarking.setCreatedTime(new Timestamp(DateUtil.current()));
                save(wipMarking);
            }
        });
        return true;
    }

    @Override
    public Boolean saveOrUpdateBatchByDTOList(List<WipMarkingDTO> wipMarkingDTOList) {

        List<WipMarking> wipMarkingList = BeanUtils.copyProperties(wipMarkingDTOList, WipMarking.class);
        return saveOrUpdateBatch(wipMarkingList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteWipMarkingLogical(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        WipMarking wipMarking = this.getById(id);

        if (ObjectUtil.isNull(wipMarking)) {
            log.error("deleteWipMarking() The WipMarking does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }

        transactionTemplate.executeWithoutResult(transactionStatus -> {

            /// 删除关联信息
            LambdaQueryWrapper<WipMarkingReminder> wipMarkingReminderLambdaQueryWrapper = new LambdaQueryWrapper<>();
            wipMarkingReminderLambdaQueryWrapper.eq(WipMarkingReminder::getMarkingIdFk, wipMarking.getId());
            wipMarkingReminderMapper.delete(wipMarkingReminderLambdaQueryWrapper);

            LambdaQueryWrapper<WipMarkingBox> wipMarkingPrdLambdaQueryWrapper = new LambdaQueryWrapper<>();
            wipMarkingPrdLambdaQueryWrapper.eq(WipMarkingBox::getMarkingIdFk, wipMarking.getId());
            wipMarkingBoxMapper.delete(wipMarkingPrdLambdaQueryWrapper);

            LambdaQueryWrapper<WipMarkingPrd> wipMarkingPrdLambda = new LambdaQueryWrapper<>();
            wipMarkingPrdLambda.eq(WipMarkingPrd::getMarkingIdFk, wipMarking.getId());
            wipMarkingPrdMapper.delete(wipMarkingPrdLambda);

            this.removeById(id);

        });

        return true;

    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteWipMarkingByIds(String ids) {
        Assert.notNull(ids, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());
        List<String> idList = Arrays.asList(ids.split(","));
        if (CollectionUtil.isEmpty(idList)) {
            throw new XdcWebException(ResponseEnum.ERROR);
        }
        idList.forEach(id -> {
            WipMarking wipMarking = this.getById(id);
            if (ObjectUtil.isNull(wipMarking)) {
                log.error("deleteWipMarking() The WipMarking does not exist or has been deleted");
                throw new XdcWebException(ResponseEnum.ERROR);
            }
        });

        return this.removeByIds(idList);
    }

    private List<WipMarking> queryWipMarkingList(WipMarkingFilterDTO wipMarkingFilterDTO) {
        WipMarkingQuery wipMarkingQuery = BeanUtil.copyProperties(wipMarkingFilterDTO, WipMarkingQuery.class);

        return wipMarkingMapper.queryWipMarking(wipMarkingQuery);
    }

    @Override
    public List<WipMarkingVO> queryWipMarkingVOList(WipMarkingFilterDTO wipMarkingFilterDTO) {
        return this.objectConversion(queryWipMarkingList(wipMarkingFilterDTO));
    }


    @Job("updateMarkingCurrentOpeCodeHandle")
    public void updateMarkingCurrentOpeCode() {
        BdPathQuery bdPathQuery = new BdPathQuery();
        List<BdPath> bdPaths = bdPathMapper.queryBdPath(bdPathQuery);

        WipMarkingFilterDTO wipMarkingFilterDTO = new WipMarkingFilterDTO();
        wipMarkingFilterDTO.setMarkStatus(1L);
        List<WipMarking> wipMarkingList = queryWipMarkingList(wipMarkingFilterDTO);
        for (WipMarking record : wipMarkingList) {

            List<String> opeCodeList;
            if (record.getMarkCreatedType() == 2) {
                opeCodeList = tracePrdInfoMapper.queryOpeCodeByMarkingCode(record.getMarkCode());
            } else {
                WipUnpackPlan wipUnpackPlan = wipUnpackPlanService.getOne(new LambdaQueryWrapper<WipUnpackPlan>().eq(WipUnpackPlan::getPlanCode, record.getMarkCode()));
                opeCodeList = tracePrdInfoMapper.queryOpeCOdeByBatchNo(wipUnpackPlan);
            }

            if (CollectionUtil.isNotEmpty(opeCodeList)) {
                // 获取 crOpeSeqNo 最大的 opeCode
                String maxCrOpeSeqNoOpeCode = bdPaths.stream()
                        .filter(bdPath -> opeCodeList.contains(bdPath.getCrOpeCode()))
                        .max(Comparator.comparing(BdPath::getCrOpeSeqNo))
                        .map(BdPath::getCrOpeCode)
                        .orElse(null);
                updateCurrentOpeCodeByMarkingId(record.getId(),maxCrOpeSeqNoOpeCode);
            }

        }


    }

    private void updateCurrentOpeCodeByMarkingId(Long id, String maxCrOpeSeqNoOpeCode) {
        transactionTemplate.executeWithoutResult(
                transactionStatus -> {
                    baseMapper.updateCurrentOpeCodeByMarkingId(id,maxCrOpeSeqNoOpeCode);
                }
        );
    }

    @Override
    public PageVO<WipMarkingVO> queryWipMarking(WipMarkingFilterDTO wipMarkingFilterDTO) {
        PageVO<WipMarkingVO> pageVO = new PageVO<>();

        if (wipMarkingFilterDTO.getCurrentPage() > NumberConstant.ZERO) {
            PageableUtils.basicPage(wipMarkingFilterDTO.getCurrentPage(), wipMarkingFilterDTO.getPageSize(),
                    wipMarkingFilterDTO.getOrderType(), wipMarkingFilterDTO.getOrderField());
        }

        List<WipMarking> wipMarkingList = queryWipMarkingList(wipMarkingFilterDTO);

        PageInfo<WipMarking> pageInfo = new PageInfo<>(wipMarkingList);
        List<WipMarkingVO> records = this.objectConversion(wipMarkingList);
        List<String> opeCodes = records.stream().map(record -> {
            List<String> opeList = Arrays.stream(record.getWarnOpeCodes().split(",")).collect(Collectors.toList());
            opeList.add(record.getStartOpeCode());
            return opeList;
        }).flatMap(Collection::stream).distinct().collect(Collectors.toList());

        if (ObjectUtil.isNotEmpty(opeCodes)) {
            Map<String, String> opeCodeMap = bdOpeService.getOpeByOpeCodes(opeCodes).stream().collect(Collectors.toMap(BdOpeVO::getOpeCode,
                    BdOpeVO::getOpeName));

            records.forEach(record -> {
                if (record.getMarkCreatedType() == 2) {
                    List<WipMarkingPrd> wipMarkingPrdList = wipMarkingPrdMapper.selectList(new LambdaQueryWrapper<WipMarkingPrd>().eq(WipMarkingPrd::getMarkCode, record.getMarkCode()));
                    record.setPrdCodeList(BeanUtils.copyProperties(wipMarkingPrdList, WipMarkingPrdVO.class));
                } else {
                    WipUnpackPlan wipUnpackPlan = wipUnpackPlanService.getOne(new LambdaQueryWrapper<WipUnpackPlan>().eq(WipUnpackPlan::getPlanCode, record.getMarkCode()));
                    record.setSuppliedBatch(wipUnpackPlan.getSuppliedBatch());
                }

                if (ObjectUtil.isNotNull(record.getStartOpeCode())) {
                    record.setStartOpeName(opeCodeMap.get(record.getStartOpeCode()));
                }

                if (ObjectUtil.isNotNull(record.getCurrentOpeCode())) {
                    record.setCurrentOpeCode(opeCodeMap.get(record.getCurrentOpeCode()));
                }

                if (ObjectUtil.isNotNull(record.getWarnOpeCodes())) {
                    record.setWarnOpeCodeNames(
                            Arrays.stream(record.getWarnOpeCodes().split(",")).map(opeCodeMap::get).collect(Collectors.joining(","))
                    );
                }

                record.setCreatedUser(record.getCreatedUser());


            });

        }


        PropertyUtils.copyProperties(pageInfo, pageVO, records);

        return pageVO;
    }

    @Override
    public WipMarkingVO queryWipMarkingById(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        return this.objectConversion(this.getById(id));
    }

    @Override
    public void closeBatchForMarking(Long markingId) {
        /// 修改marking状态
        transactionTemplate.executeWithoutResult(transactionStatus -> {
            Timestamp nowTime=new Timestamp(DateUtil.current());
            WipMarking wipMarking=  this.getById(markingId);
            if(wipMarking==null){
                throw new IllegalArgumentException("标记不存在");
            }
            if(wipMarking.getMarkStatus()!= MarkingStatusEnum.RUNNING.getCode()){
               throw new IllegalArgumentException("标记状态不是进行中，不能结批");
            }
            wipMarking.setUpdatedUser(AuthUtils.getCurrentUser());
            wipMarking.setUpdatedTime(nowTime);
            wipMarking.setCloseTime(nowTime);
            wipMarking.setMarkStatus((long) MarkingStatusEnum.STOP.getCode());
            this.updateById(wipMarking);
        if(markingSwitchProperties.getIsBatchWash()) {
            List<WipMarkingElSummaryDTO> wipMarkingElSummaryList = submitQueryWipMarkingElSummary(wipMarking);
            List<WipMarkingIvCountDTO> wipMarkingIvCountList = submitWipMarkingIvCount(wipMarking);
            List<WipMarkingIvSummaryDTO> wipMarkingIvSummaryList = submitWipMarkingIvSummary(wipMarking);
            List<WipMarkingPackInfoDTO> wipMarkingPackInfoList = submitWipMarkingPackInfo(wipMarking);
            List<WipMarkingScreenDTO> wipMarkingScreenDTOList=  submitQueryMarkingScreen(wipMarking);
            if (CollectionUtil.isNotEmpty(wipMarkingElSummaryList)) {
                wipMarkingElSummaryList.forEach(wipMarkingElSummaryDTO -> {
                    wipMarkingElSummaryDTO.setMarkingIdFk(wipMarking.getId());
                    wipMarkingElSummaryDTO.setMarkCode(wipMarking.getMarkCode());
                    wipMarkingElSummaryDTO.setCreatedTime(nowTime);
                    wipMarkingElSummaryDTO.setCreatedUser(AuthUtils.getCurrentUser());
                });
                wipMarkingElSummaryService.saveOrUpdateBatchByDTOList(wipMarkingElSummaryList);
            }
            if (CollectionUtil.isNotEmpty(wipMarkingIvCountList)) {
                wipMarkingIvCountList.forEach(wipMarkingIvCountDTO -> {
                    wipMarkingIvCountDTO.setMarkingIdFk(wipMarking.getId());
                    wipMarkingIvCountDTO.setMarkCode(wipMarking.getMarkCode());
                    wipMarkingIvCountDTO.setCreatedTime(nowTime);
                    wipMarkingIvCountDTO.setCreatedUser(AuthUtils.getCurrentUser());
                });
                wipMarkingIvCountService.saveOrUpdateBatchByDTOList(wipMarkingIvCountList);
            }
            if (CollectionUtil.isNotEmpty(wipMarkingIvSummaryList)) {
                wipMarkingIvSummaryList.forEach(wipMarkingIvSummaryDTO -> {
                    wipMarkingIvSummaryDTO.setMarkingIdFk(wipMarking.getId());
                    wipMarkingIvSummaryDTO.setMarkCode(wipMarking.getMarkCode());
                    wipMarkingIvSummaryDTO.setCreatedTime(nowTime);
                    wipMarkingIvSummaryDTO.setCreatedUser(AuthUtils.getCurrentUser());
                });
                wipMarkingIvSummaryService.saveOrUpdateBatchByDTOList(wipMarkingIvSummaryList);
            }
            if (CollectionUtil.isNotEmpty(wipMarkingPackInfoList)) {
                wipMarkingPackInfoList.forEach(wipMarkingPackInfoDTO -> {
                    wipMarkingPackInfoDTO.setMarkingIdFk(wipMarking.getId());
                    wipMarkingPackInfoDTO.setMarkCode(wipMarking.getMarkCode());
                    wipMarkingPackInfoDTO.setCreatedTime(nowTime);
                    wipMarkingPackInfoDTO.setCreatedUser(AuthUtils.getCurrentUser());
                });
                wipMarkingPackInfoService.saveOrUpdateBatchByDTOList(wipMarkingPackInfoList);
            }
            if(CollectionUtil.isNotEmpty(wipMarkingScreenDTOList)){
                wipMarkingScreenDTOList.forEach(wipMarkingScreenDTO -> {
                    wipMarkingScreenDTO.setMarkingIdFk(wipMarking.getId());
                    wipMarkingScreenDTO.setMarkCode(wipMarking.getMarkCode());
                    wipMarkingScreenDTO.setCreatedTime(nowTime);
                    wipMarkingScreenDTO.setCreatedUser(AuthUtils.getCurrentUser());
                });
                wipMarkingScreenService.saveOrUpdateBatchByDTOList(wipMarkingScreenDTOList);
            }
        }
        });
    }

    private List<WipMarkingPackInfoDTO> submitWipMarkingPackInfo(WipMarking wipMarking) {
        return getFutureResult(CompletableFuture.supplyAsync(() ->
                wipMarkingMapper.queryWipMarkingPackInfo(DateUtils.formatTimestamp(wipMarking.getCreatedTime()),DateUtils.formatTimestamp(wipMarking.getCloseTime()),wipMarking.getId()), threadPoolExecutor));
    }

    private List<WipMarkingScreenDTO> submitQueryMarkingScreen(WipMarking wipMarking){

        return getFutureResult(CompletableFuture.supplyAsync(() ->
                wipMarkingMapper.queryMarkingScreen(DateUtils.formatTimestamp(wipMarking.getCreatedTime()),DateUtils.formatTimestamp(wipMarking.getCloseTime()),wipMarking.getId()), threadPoolExecutor));
    }


    private List<WipMarkingIvSummaryDTO> submitWipMarkingIvSummary(WipMarking wipMarking) {
        return getFutureResult(CompletableFuture.supplyAsync(() ->
                wipMarkingMapper.queryWipMarkingIvSummary(wipMarking.getCreatedTime(),wipMarking.getCloseTime(),wipMarking.getId()), threadPoolExecutor));
    }

    private List<WipMarkingIvCountDTO> submitWipMarkingIvCount(WipMarking wipMarking) {
        return getFutureResult(CompletableFuture.supplyAsync(() ->
                wipMarkingMapper.queryWipMarkingIvCount(wipMarking.getCreatedTime(),wipMarking.getCloseTime(),wipMarking.getId()), threadPoolExecutor));
    }

    private List<WipMarkingElSummaryDTO> submitQueryWipMarkingElSummary(WipMarking wipMarking) {
            return getFutureResult(CompletableFuture.supplyAsync(() ->
                    wipMarkingMapper.queryWipMarkingElSummary(wipMarking.getCreatedTime(),wipMarking.getCloseTime(),wipMarking.getId()), threadPoolExecutor));
    }


    private <T> T getFutureResult(CompletableFuture<T> future) {
        try {
            return future.get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }



    @Override
    public Map<String, Object> queryMarkingReport(Long wipMarkingId) {
        List<WipMarkingIvCountVO> ivSummaryCountVOS = wipMarkingIvCountService.queryByMarkingId(wipMarkingId);
        WipMarkingIvCountVO ivSummaryCount = ObjectUtil.isEmpty(ivSummaryCountVOS) ? new WipMarkingIvCountVO() : ivSummaryCountVOS.get(0);
        String rEta = ivSummaryCount.getReta();
        Map<String, Object> reportMap = new HashMap<>();
        reportMap.put("screen", wipMarkingScreenService.queryByMarkingId(wipMarkingId));
        reportMap.put("ivEta", wipMarkingIvSummaryService.queryByMarkingId(wipMarkingId));
        reportMap.put("a-", wipMarkingElSummaryService.queryByMarkingIdAndReportType(wipMarkingId,"a-"));
        reportMap.put("bz", wipMarkingElSummaryService.queryByMarkingIdAndReportType(wipMarkingId,"bz"));
        reportMap.put("bb", wipMarkingElSummaryService.queryByMarkingIdAndReportType(wipMarkingId,"bb"));
        reportMap.put("pack", wipMarkingPackInfoService.queryByMarkingId(wipMarkingId));
        reportMap.put("rEta", rEta);
        reportMap.put("zmColor", wipMarkingElSummaryService.queryByMarkingIdAndReportType(wipMarkingId,"zmColor"));
        reportMap.put("cSummary", wipMarkingElSummaryService.queryByMarkingIdAndReportType(wipMarkingId,"cSummary"));
        reportMap.put("ivSummaryCount", ivSummaryCount);
        return reportMap;
    }

    @Override
    public Object markingReport(Long wipMarkingId) {
        Assert.notNull(wipMarkingId, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        WipMarking wipMarking = this.getById(wipMarkingId);

        Assert.notNull(wipMarking, "标记不存在");


        //过程信息

        //成品信息

        //成品率信息


        List<TracePrdInfo> infoList = tracePrdInfoMapper.queryByMarkingId(wipMarkingId);
        if (CollUtil.isNotEmpty(infoList)) {
            WipMarkingReportVO report = new WipMarkingReportVO();
            //TODO 数据组装
            return report;
        }
        return null;
    }



    @Override
    public List<WipMarkingRecordVO> queryWipMarkingFlow(Long wipMarkingId) {
        WipMarking wipMarking = getById(wipMarkingId);
        WipMarkingPrdFilterDTO wipMarkingPrdFilterDTO = new WipMarkingPrdFilterDTO();
        wipMarkingPrdFilterDTO.setMarkCode(wipMarking.getMarkCode());
        List<WipMarkingPrdVO> wipMarkingPrdVOS = wipMarkingPrdService.queryWipMarkingPrdVOList(wipMarkingPrdFilterDTO);
        if (ObjectUtil.isEmpty(wipMarkingPrdVOS)) {
            return Collections.emptyList();
        }
        List<WipMarkingRecordVO> wipMarkingReportVOS = tracePrdInfoMapper.queryWipMarkingFlow(wipMarkingPrdVOS.stream().map(WipMarkingPrdVO::getPrdCode).distinct().collect(Collectors.toList()));

        List<String> opePathiMain = baseMapper.getOpePathiMain();

        List<WipMarkingRecordVO> newMarkingReportVOS = new ArrayList<>();
        for (String opePath : opePathiMain) {

            List<WipMarkingRecordVO> wipMarkingRecordVOList =
                    wipMarkingReportVOS.stream().filter(v -> opePath.equals(v.getOpeCode()))
                            .sorted(Comparator.comparing(WipMarkingRecordVO::getToolCode)).collect(Collectors.toList());
            newMarkingReportVOS.addAll(wipMarkingRecordVOList);

        }


        return newMarkingReportVOS;
    }

}
